package com.martian.common.interceptor;

import com.martian.common.constant.TokenInfo;
import com.martian.common.enums.BaseErrorCodeEnum;
import com.martian.common.util.JsonUtil;
import com.martian.common.util.ThreadLocalMap;
import com.martian.common.wrapper.ResultWrapper;
import com.martian.service.redis.RedisRepository;
import com.martian.service.token.TokenService;
//import io.netty.handler.codec.http.HttpMethod;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;


/**
 * @author martian
 * @version V1.0.0
 * @Description
 * @date 2023-03-20 9:25
 */
@Component
public class LoginInterceptor implements HandlerInterceptor {
    @Resource
    private TokenService tokenService;
    @Resource
    private RedisRepository redisRepository;
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler){
        if (request.getMethod().equalsIgnoreCase("options")) {
            return true;
        }
        String accessToken = request.getHeader("recToken");
        if(accessToken == null){
            accessToken = request.getParameter("recToken");
        }
        //可以是游客模式访问，也可以是登录状态访问
        if (request.getServletPath().equals("/movie/mayBeVisitor/getMovieById")){
            if (accessToken == null){
                return true;
            }
        }
        ResultWrapper resultWrapper = null;
        response.setHeader("Content-Type", "application/json;charset=utf-8");
        if (null == accessToken || "".equals(accessToken)){//找不到Token则终止继续进入服务
            ThreadLocalMap.remove("THREAD_LOCAL_KEY_LOGIN_USER");
            resultWrapper = ResultWrapper.failure("未认证");
            //SC_UNAUTHORIZED  =  401
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
            try {
                //输出未认证的报错信息
                System.out.println("未认证");
                response.getWriter().println(JsonUtil.toJson(resultWrapper));
            } catch (IOException e) {
                e.printStackTrace();
            }
            return false;
        }
        // 这里是确保有token，但不一定正确，有可能被篡改
//        @TODO 这里只查询了普通用户的Token，管理员Token没有查询
        TokenInfo tokenInfo = tokenService.getTokenInfo(accessToken);
        if (tokenInfo == null){
            // 查询是否为管理员登录
            tokenInfo = tokenService.getManagerTokenInfo(accessToken);
            if(tokenInfo == null){
                ThreadLocalMap.remove("THREAD_LOCAL_KEY_LOGIN_USER");
                resultWrapper = ResultWrapper.failure(BaseErrorCodeEnum.LOGIN_OVERTIME_ERROR);
                response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
                try {
                    response.getWriter().println(JsonUtil.toJson(resultWrapper));
                } catch (Exception e) {
                    e.printStackTrace();
                }
                return false;
            }else{
                redisRepository.saveManagerLoginId(tokenInfo);
                redisRepository.saveManagerLoginToken(tokenInfo);
                ThreadLocalMap.put("THREAD_LOCAL_KEY_LOGIN_MANAGER", tokenInfo.getUserId());
                return true;
            }
        }
        //@TODO 这里存在bug，TOKEN没有对用户ID进行校验
        //每次刷新token
        redisRepository.saveAccessToken(tokenInfo);
        redisRepository.saveLoginAccessToken(tokenInfo);
        ThreadLocalMap.put("THREAD_LOCAL_KEY_LOGIN_USER", tokenInfo.getUserId());
        return true;
    }
}
